/*   1:    */ package nl.siegmann.epublib.viewer;
/*   2:    */ 
/*   3:    */ import java.awt.Color;
/*   4:    */ import java.awt.GridLayout;
/*   5:    */ import java.awt.Point;
/*   6:    */ import java.awt.Rectangle;
/*   7:    */ import java.awt.event.KeyEvent;
/*   8:    */ import java.awt.event.KeyListener;
/*   9:    */ import java.awt.event.MouseWheelEvent;
/*  10:    */ import java.awt.event.MouseWheelListener;
/*  11:    */ import java.io.UnsupportedEncodingException;
/*  12:    */ import java.net.URL;
/*  13:    */ import java.net.URLDecoder;
/*  14:    */ import javax.swing.JEditorPane;
/*  15:    */ import javax.swing.JPanel;
/*  16:    */ import javax.swing.JScrollBar;
/*  17:    */ import javax.swing.JScrollPane;
/*  18:    */ import javax.swing.JViewport;
/*  19:    */ import javax.swing.event.HyperlinkEvent;
/*  20:    */ import javax.swing.event.HyperlinkEvent.EventType;
/*  21:    */ import javax.swing.event.HyperlinkListener;
/*  22:    */ import javax.swing.text.AttributeSet;
/*  23:    */ import javax.swing.text.BadLocationException;
/*  24:    */ import javax.swing.text.Document;
/*  25:    */ import javax.swing.text.html.HTML.Attribute;
/*  26:    */ import javax.swing.text.html.HTML.Tag;
/*  27:    */ import javax.swing.text.html.HTMLDocument;
/*  28:    */ import javax.swing.text.html.HTMLDocument.Iterator;
/*  29:    */ import javax.swing.text.html.HTMLEditorKit;
/*  30:    */ import nl.siegmann.epublib.browsersupport.NavigationEvent;
/*  31:    */ import nl.siegmann.epublib.browsersupport.NavigationEventListener;
/*  32:    */ import nl.siegmann.epublib.browsersupport.Navigator;
/*  33:    */ import nl.siegmann.epublib.domain.Book;
/*  34:    */ import nl.siegmann.epublib.domain.Resource;
/*  35:    */ import nl.siegmann.epublib.domain.Resources;
/*  36:    */ import nl.siegmann.epublib.util.DesktopUtil;
/*  37:    */ import nl.siegmann.epublib.util.DesktopUtil.BrowserLaunchException;
/*  38:    */ import org.apache.commons.lang.StringUtils;
/*  39:    */ import org.slf4j.Logger;
/*  40:    */ import org.slf4j.LoggerFactory;
/*  41:    */ 
/*  42:    */ public class ContentPane
/*  43:    */   extends JPanel
/*  44:    */   implements NavigationEventListener, HyperlinkListener
/*  45:    */ {
/*  46:    */   private static final long serialVersionUID = -5322988066178102320L;
/*  47: 48 */   private static final Logger log = LoggerFactory.getLogger(ContentPane.class);
/*  48:    */   private Navigator navigator;
/*  49:    */   private Resource currentResource;
/*  50:    */   private JEditorPane editorPane;
/*  51:    */   private JScrollPane scrollPane;
/*  52:    */   private HTMLDocumentFactory htmlDocumentFactory;
/*  53:    */   
/*  54:    */   public ContentPane(Navigator navigator)
/*  55:    */   {
/*  56: 57 */     super(new GridLayout(1, 0));
/*  57: 58 */     this.scrollPane = ((JScrollPane)add(new JScrollPane()));
/*  58: 59 */     this.scrollPane.addKeyListener(new KeyListener()
/*  59:    */     {
/*  60:    */       public void keyTyped(KeyEvent e) {}
/*  61:    */       
/*  62:    */       public void keyReleased(KeyEvent e) {}
/*  63:    */       
/*  64:    */       public void keyPressed(KeyEvent e)
/*  65:    */       {
/*  66: 75 */         if (e.getKeyCode() == 40)
/*  67:    */         {
/*  68: 76 */           Point viewPosition = ContentPane.this.scrollPane.getViewport().getViewPosition();
/*  69: 77 */           int newY = (int)(viewPosition.getY() + 10.0D);
/*  70: 78 */           ContentPane.this.scrollPane.getViewport().setViewPosition(new Point((int)viewPosition.getX(), newY));
/*  71:    */         }
/*  72:    */       }
/*  73: 81 */     });
/*  74: 82 */     this.scrollPane.addMouseWheelListener(new MouseWheelListener()
/*  75:    */     {
/*  76: 84 */       private boolean gotoNextPage = false;
/*  77: 85 */       private boolean gotoPreviousPage = false;
/*  78:    */       
/*  79:    */       public void mouseWheelMoved(MouseWheelEvent e)
/*  80:    */       {
/*  81: 89 */         int notches = e.getWheelRotation();
/*  82: 90 */         int increment = ContentPane.this.scrollPane.getVerticalScrollBar().getUnitIncrement(1);
/*  83: 91 */         if (notches < 0)
/*  84:    */         {
/*  85: 92 */           Point viewPosition = ContentPane.this.scrollPane.getViewport().getViewPosition();
/*  86: 93 */           if (viewPosition.getY() - increment < 0.0D) {
/*  87: 94 */             if (this.gotoPreviousPage)
/*  88:    */             {
/*  89: 95 */               this.gotoPreviousPage = false;
/*  90: 96 */               ContentPane.this.navigator.gotoPreviousSpineSection(-1, ContentPane.this);
/*  91:    */             }
/*  92:    */             else
/*  93:    */             {
/*  94: 98 */               this.gotoPreviousPage = true;
/*  95: 99 */               ContentPane.this.scrollPane.getViewport().setViewPosition(new Point((int)viewPosition.getX(), 0));
/*  96:    */             }
/*  97:    */           }
/*  98:    */         }
/*  99:    */         else
/* 100:    */         {
/* 101:104 */           Point viewPosition = ContentPane.this.scrollPane.getViewport().getViewPosition();
/* 102:105 */           int viewportHeight = ContentPane.this.scrollPane.getViewport().getHeight();
/* 103:106 */           int scrollMax = ContentPane.this.scrollPane.getVerticalScrollBar().getMaximum();
/* 104:107 */           if (viewPosition.getY() + viewportHeight + increment > scrollMax) {
/* 105:108 */             if (this.gotoNextPage)
/* 106:    */             {
/* 107:109 */               this.gotoNextPage = false;
/* 108:110 */               ContentPane.this.navigator.gotoNextSpineSection(ContentPane.this);
/* 109:    */             }
/* 110:    */             else
/* 111:    */             {
/* 112:112 */               this.gotoNextPage = true;
/* 113:113 */               int newY = scrollMax - viewportHeight;
/* 114:114 */               ContentPane.this.scrollPane.getViewport().setViewPosition(new Point((int)viewPosition.getX(), newY));
/* 115:    */             }
/* 116:    */           }
/* 117:    */         }
/* 118:    */       }
/* 119:119 */     });
/* 120:120 */     this.navigator = navigator;
/* 121:121 */     navigator.addNavigationEventListener(this);
/* 122:122 */     this.editorPane = createJEditorPane();
/* 123:123 */     this.scrollPane.getViewport().add(this.editorPane);
/* 124:124 */     this.htmlDocumentFactory = new HTMLDocumentFactory(navigator, this.editorPane.getEditorKit());
/* 125:125 */     initBook(navigator.getBook());
/* 126:    */   }
/* 127:    */   
/* 128:    */   private void initBook(Book book)
/* 129:    */   {
/* 130:129 */     if (book == null) {
/* 131:130 */       return;
/* 132:    */     }
/* 133:132 */     this.htmlDocumentFactory.init(book);
/* 134:133 */     displayPage(book.getCoverPage());
/* 135:    */   }
/* 136:    */   
/* 137:    */   private static boolean matchesAny(String searchString, String... possibleValues)
/* 138:    */   {
/* 139:146 */     for (int i = 0; i < possibleValues.length; i++)
/* 140:    */     {
/* 141:147 */       String attributeValue = possibleValues[i];
/* 142:148 */       if ((StringUtils.isNotBlank(attributeValue)) && (attributeValue.equals(searchString))) {
/* 143:149 */         return true;
/* 144:    */       }
/* 145:    */     }
/* 146:152 */     return false;
/* 147:    */   }
/* 148:    */   
/* 149:    */   private static void scrollToElement(JEditorPane editorPane, HTMLDocument.Iterator elementIterator)
/* 150:    */   {
/* 151:    */     try
/* 152:    */     {
/* 153:168 */       Rectangle rectangle = editorPane.modelToView(elementIterator.getStartOffset());
/* 154:169 */       if (rectangle == null) {
/* 155:170 */         return;
/* 156:    */       }
/* 157:174 */       Rectangle visibleRectangle = editorPane.getVisibleRect();
/* 158:    */       
/* 159:176 */       rectangle.height = visibleRectangle.height;
/* 160:177 */       editorPane.scrollRectToVisible(rectangle);
/* 161:    */     }
/* 162:    */     catch (BadLocationException e)
/* 163:    */     {
/* 164:179 */       log.error(e.getMessage());
/* 165:    */     }
/* 166:    */   }
/* 167:    */   
/* 168:    */   private void scrollToNamedAnchor(String fragmentId)
/* 169:    */   {
/* 170:190 */     HTMLDocument doc = (HTMLDocument)this.editorPane.getDocument();
/* 171:191 */     for (HTMLDocument.Iterator iter = doc.getIterator(HTML.Tag.A); iter.isValid(); iter.next())
/* 172:    */     {
/* 173:192 */       AttributeSet attributes = iter.getAttributes();
/* 174:193 */       if (matchesAny(fragmentId, new String[] { (String)attributes.getAttribute(HTML.Attribute.NAME), (String)attributes.getAttribute(HTML.Attribute.ID) }))
/* 175:    */       {
/* 176:195 */         scrollToElement(this.editorPane, iter);
/* 177:196 */         break;
/* 178:    */       }
/* 179:    */     }
/* 180:    */   }
/* 181:    */   
/* 182:    */   private JEditorPane createJEditorPane()
/* 183:    */   {
/* 184:202 */     JEditorPane editorPane = new JEditorPane();
/* 185:203 */     editorPane.setBackground(Color.white);
/* 186:204 */     editorPane.setEditable(false);
/* 187:205 */     HTMLEditorKit htmlKit = new HTMLEditorKit();
/* 188:    */     
/* 189:    */ 
/* 190:    */ 
/* 191:    */ 
/* 192:    */ 
/* 193:    */ 
/* 194:212 */     editorPane.setEditorKit(htmlKit);
/* 195:213 */     editorPane.addHyperlinkListener(this);
/* 196:214 */     editorPane.addKeyListener(new KeyListener()
/* 197:    */     {
/* 198:    */       public void keyTyped(KeyEvent keyEvent) {}
/* 199:    */       
/* 200:    */       public void keyReleased(KeyEvent e) {}
/* 201:    */       
/* 202:    */       public void keyPressed(KeyEvent keyEvent)
/* 203:    */       {
/* 204:228 */         if (keyEvent.getKeyCode() == 39) {
/* 205:229 */           ContentPane.this.navigator.gotoNextSpineSection(ContentPane.this);
/* 206:230 */         } else if (keyEvent.getKeyCode() == 37) {
/* 207:231 */           ContentPane.this.navigator.gotoPreviousSpineSection(ContentPane.this);
/* 208:234 */         } else if (keyEvent.getKeyCode() == 32) {
/* 209:236 */           ContentPane.this.gotoNextPage();
/* 210:    */         }
/* 211:    */       }
/* 212:239 */     });
/* 213:240 */     return editorPane;
/* 214:    */   }
/* 215:    */   
/* 216:    */   public void displayPage(Resource resource)
/* 217:    */   {
/* 218:244 */     displayPage(resource, 0);
/* 219:    */   }
/* 220:    */   
/* 221:    */   public void displayPage(Resource resource, int sectionPos)
/* 222:    */   {
/* 223:248 */     if (resource == null) {
/* 224:249 */       return;
/* 225:    */     }
/* 226:    */     try
/* 227:    */     {
/* 228:252 */       HTMLDocument document = this.htmlDocumentFactory.getDocument(resource);
/* 229:253 */       if (document == null) {
/* 230:254 */         return;
/* 231:    */       }
/* 232:256 */       this.currentResource = resource;
/* 233:257 */       this.editorPane.setDocument(document);
/* 234:258 */       scrollToCurrentPosition(sectionPos);
/* 235:    */     }
/* 236:    */     catch (Exception e)
/* 237:    */     {
/* 238:260 */       log.error("When reading resource " + resource.getId() + "(" + resource.getHref() + ") :" + e.getMessage(), e);
/* 239:    */     }
/* 240:    */   }
/* 241:    */   
/* 242:    */   private void scrollToCurrentPosition(int sectionPos)
/* 243:    */   {
/* 244:266 */     if (sectionPos < 0) {
/* 245:267 */       this.editorPane.setCaretPosition(this.editorPane.getDocument().getLength());
/* 246:    */     } else {
/* 247:269 */       this.editorPane.setCaretPosition(sectionPos);
/* 248:    */     }
/* 249:271 */     if (sectionPos == 0)
/* 250:    */     {
/* 251:272 */       this.scrollPane.getViewport().setViewPosition(new Point(0, 0));
/* 252:    */     }
/* 253:273 */     else if (sectionPos < 0)
/* 254:    */     {
/* 255:274 */       int viewportHeight = this.scrollPane.getViewport().getHeight();
/* 256:275 */       int scrollMax = this.scrollPane.getVerticalScrollBar().getMaximum();
/* 257:276 */       this.scrollPane.getViewport().setViewPosition(new Point(0, scrollMax - viewportHeight));
/* 258:    */     }
/* 259:    */   }
/* 260:    */   
/* 261:    */   public void hyperlinkUpdate(HyperlinkEvent event)
/* 262:    */   {
/* 263:281 */     if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) {
/* 264:282 */       return;
/* 265:    */     }
/* 266:284 */     URL url = event.getURL();
/* 267:285 */     if ((url.getProtocol().toLowerCase().startsWith("http")) && (!"".equals(url.getHost()))) {
/* 268:    */       try
/* 269:    */       {
/* 270:287 */         DesktopUtil.launchBrowser(event.getURL());
/* 271:288 */         return;
/* 272:    */       }
/* 273:    */       catch (DesktopUtil.BrowserLaunchException ex)
/* 274:    */       {
/* 275:290 */         log.warn("Couldn't launch system web browser.", ex);
/* 276:    */       }
/* 277:    */     }
/* 278:293 */     String resourceHref = calculateTargetHref(event.getURL());
/* 279:294 */     if (resourceHref.startsWith("#"))
/* 280:    */     {
/* 281:295 */       scrollToNamedAnchor(resourceHref.substring(1));
/* 282:296 */       return;
/* 283:    */     }
/* 284:299 */     Resource resource = this.navigator.getBook().getResources().getByHref(resourceHref);
/* 285:300 */     if (resource == null) {
/* 286:301 */       log.error("Resource with url " + resourceHref + " not found");
/* 287:    */     } else {
/* 288:303 */       this.navigator.gotoResource(resource, this);
/* 289:    */     }
/* 290:    */   }
/* 291:    */   
/* 292:    */   public void gotoPreviousPage()
/* 293:    */   {
/* 294:308 */     Point viewPosition = this.scrollPane.getViewport().getViewPosition();
/* 295:309 */     if (viewPosition.getY() <= 0.0D)
/* 296:    */     {
/* 297:310 */       this.navigator.gotoPreviousSpineSection(this);
/* 298:311 */       return;
/* 299:    */     }
/* 300:313 */     int viewportHeight = this.scrollPane.getViewport().getHeight();
/* 301:314 */     int newY = (int)viewPosition.getY();
/* 302:315 */     newY -= viewportHeight;
/* 303:316 */     newY = Math.max(0, newY - viewportHeight);
/* 304:317 */     this.scrollPane.getViewport().setViewPosition(new Point((int)viewPosition.getX(), newY));
/* 305:    */   }
/* 306:    */   
/* 307:    */   public void gotoNextPage()
/* 308:    */   {
/* 309:322 */     Point viewPosition = this.scrollPane.getViewport().getViewPosition();
/* 310:323 */     int viewportHeight = this.scrollPane.getViewport().getHeight();
/* 311:324 */     int scrollMax = this.scrollPane.getVerticalScrollBar().getMaximum();
/* 312:325 */     if (viewPosition.getY() + viewportHeight >= scrollMax)
/* 313:    */     {
/* 314:326 */       this.navigator.gotoNextSpineSection(this);
/* 315:327 */       return;
/* 316:    */     }
/* 317:329 */     int newY = (int)viewPosition.getY() + viewportHeight;
/* 318:330 */     this.scrollPane.getViewport().setViewPosition(new Point((int)viewPosition.getX(), newY));
/* 319:    */   }
/* 320:    */   
/* 321:    */   private String calculateTargetHref(URL clickUrl)
/* 322:    */   {
/* 323:343 */     String resourceHref = clickUrl.toString();
/* 324:    */     try
/* 325:    */     {
/* 326:345 */       resourceHref = URLDecoder.decode(resourceHref, "UTF-8");
/* 327:    */     }
/* 328:    */     catch (UnsupportedEncodingException e)
/* 329:    */     {
/* 330:348 */       log.error(e.getMessage());
/* 331:    */     }
/* 332:350 */     resourceHref = resourceHref.substring("http:/".length());
/* 333:353 */     if (resourceHref.startsWith("#")) {
/* 334:354 */       return resourceHref;
/* 335:    */     }
/* 336:356 */     if ((this.currentResource != null) && (StringUtils.isNotBlank(this.currentResource.getHref())))
/* 337:    */     {
/* 338:358 */       int lastSlashPos = this.currentResource.getHref().lastIndexOf('/');
/* 339:359 */       if (lastSlashPos >= 0) {
/* 340:360 */         resourceHref = this.currentResource.getHref().substring(0, lastSlashPos + 1) + resourceHref;
/* 341:    */       }
/* 342:    */     }
/* 343:365 */     return resourceHref;
/* 344:    */   }
/* 345:    */   
/* 346:    */   public void navigationPerformed(NavigationEvent navigationEvent)
/* 347:    */   {
/* 348:370 */     if (navigationEvent.isBookChanged())
/* 349:    */     {
/* 350:371 */       initBook(navigationEvent.getCurrentBook());
/* 351:    */     }
/* 352:    */     else
/* 353:    */     {
/* 354:373 */       if (navigationEvent.isResourceChanged()) {
/* 355:374 */         displayPage(navigationEvent.getCurrentResource(), navigationEvent.getCurrentSectionPos());
/* 356:376 */       } else if (navigationEvent.isSectionPosChanged()) {
/* 357:377 */         this.editorPane.setCaretPosition(navigationEvent.getCurrentSectionPos());
/* 358:    */       }
/* 359:379 */       if (StringUtils.isNotBlank(navigationEvent.getCurrentFragmentId())) {
/* 360:380 */         scrollToNamedAnchor(navigationEvent.getCurrentFragmentId());
/* 361:    */       }
/* 362:    */     }
/* 363:    */   }
/* 364:    */ }


/* Location:           C:\Users\David\workspace\CosaRaraPorqueSi\main\epublib-tools-3.1.jar
 * Qualified Name:     nl.siegmann.epublib.viewer.ContentPane
 * JD-Core Version:    0.7.0.1
 */